//---------------------------------------------------------------------
// File: Logger.cs
// 
// Summary: 
//
//---------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//---------------------------------------------------------------------

namespace Microsoft.Services.BizTalkApplicationFramework.BizUnit
{
	using System;
	using System.Text;

	/// <summary>
	/// The BizUnit Logger is used to log data from BizUnit and test steps.
	/// </summary>
	internal class Logger
	{
		ILogWritter lw;
		StringBuilder sb = null;
		bool concurrentExecutionMode = false;
		const string crlf = "\r\n";

        internal Logger()
        {
            lw = new ConsoleWritter();
        }

        internal Logger(ILogWritter logWritter)
		{
            lw = logWritter;
		}

        internal Logger(bool concurrentExecutionMode)
		{
			this.concurrentExecutionMode = concurrentExecutionMode;

			if ( this.concurrentExecutionMode )
			{
				this.sb = new StringBuilder();
			}
		}

		internal void Close()
		{
		}

		internal void TestSetUp(string testName)
		{
            WriteLine(" ");
			WriteLine("Setup Test: {0}", testName);
		}

		internal void TestExecute(string testName)
		{
            WriteLine(" "); 
            WriteLine("Execute Test: {0}", testName);
		}	
		
		internal void TestTearDown(string testName)
		{
            WriteLine(" "); 
            WriteLine("Tear Down Test: {0}", testName);
		}	

		internal void WriteLine(string s)
		{
			if ( concurrentExecutionMode )
			{
				this.sb.Append(s);
				this.sb.Append(crlf);
			}
			else
			{
				lw.WriteLine(s);
			}
		}
	
		internal void WriteLine(string s, params object[] args)
		{
			if ( concurrentExecutionMode )
			{
				this.sb.Append(String.Format(s, args));
				this.sb.Append(crlf);
			}
			else
			{
				lw.WriteLine(s, args);
			}
		}

		internal void LogException(Exception e)
		{
			WriteLine(new string('*', 79));
			Log( Context.LogLevel.ERROR, "Exception caught!" );
			WriteLine( e.ToString() );
			WriteLine(new string('*', 79));
		}

		internal void LogError(string text, params object[] args)
		{
			WriteLine(new string('*', 79));
			Log( Context.LogLevel.ERROR, string.Format(text, args) );
			WriteLine(new string('*', 79));
		}

		internal void LogData(string description, string data)
		{
			WriteLine(new string('~', 79));
			WriteLine( "Data: {0}", description );
			WriteLine(new string('~', 79));
			WriteLine( data );
			WriteLine(new string('~', 79));
		}

		internal void Log(Context.LogLevel logLevel, string text)
		{
			string level;

			switch(logLevel)
			{
                case (Context.LogLevel.INFO):
					level = "Info";
					break;

                case (Context.LogLevel.WARNING):
					level = "Warning";
					break;

                case (Context.LogLevel.ERROR):
					level = "Error";
					break;

				default:
					level = "Error";
					break;
			};

			WriteLine( "{0}: {1}", level, text );
		}

		internal string GetLogText()
		{
			if ( !this.concurrentExecutionMode )
			{
				throw new ApplicationException("This instance is not a concurrent test step!");
			}

			return this.sb.ToString();
		}
	}
}
